﻿using HelixToolkit.Wpf;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Media;
using System.Windows.Media.Media3D;
using Brushes = System.Windows.Media.Brushes;

namespace TeaStlShow
{
    /// <summary>
    /// 自定义的坐标系
    /// </summary>
    public class CustomCoordinateSystem : ModelVisual3D
    {
        private TubeVisual3D xAxis, yAxis, zAxis;
        private ArrowVisual3D xArrow, yArrow, zArrow;

        private double size = 2.0;
        private double thickness = 0.05;

        public double Size
        {
            get => size;
            set
            {
                size = value;
                UpdateGeometry();
            }
        }

        public double Thickness
        {
            get => thickness;
            set
            {
                thickness = value;
                UpdateGeometry();
            }
        }

        // 新增：坐标系的变换属性，外部可设置
        public Transform3D CoordinateTransform
        {
            get => this.Transform;
            set => this.Transform = value;
        }

        public CustomCoordinateSystem()
        {
            xAxis = new TubeVisual3D { Fill = Brushes.Red };
            yAxis = new TubeVisual3D { Fill = Brushes.Green };
            zAxis = new TubeVisual3D { Fill = Brushes.Blue };

            xArrow = new ArrowVisual3D { Fill = Brushes.Red };
            yArrow = new ArrowVisual3D { Fill = Brushes.Green };
            zArrow = new ArrowVisual3D { Fill = Brushes.Blue };

            this.Children.Add(xAxis);
            this.Children.Add(yAxis);
            this.Children.Add(zAxis);
            this.Children.Add(xArrow);
            this.Children.Add(yArrow);
            this.Children.Add(zArrow);

            UpdateGeometry();
        }

        private void UpdateGeometry()
        {
            xAxis.Path = new Point3DCollection { new Point3D(0, 0, 0), new Point3D(size, 0, 0) };
            yAxis.Path = new Point3DCollection { new Point3D(0, 0, 0), new Point3D(0, size, 0) };
            zAxis.Path = new Point3DCollection { new Point3D(0, 0, 0), new Point3D(0, 0, size) };

            xAxis.Diameter = thickness;
            yAxis.Diameter = thickness;
            zAxis.Diameter = thickness;

            xArrow.Origin = new Point3D(size, 0, 0);
            xArrow.Direction = new Vector3D(1, 0, 0);
            xArrow.Diameter = thickness;
            xArrow.Point2 = new Point3D(size + thickness * 2, 0, 0);

            yArrow.Origin = new Point3D(0, size, 0);
            yArrow.Direction = new Vector3D(0, 1, 0);
            yArrow.Diameter = thickness;
            yArrow.Point2 = new Point3D(0, size + thickness * 2, 0);

            zArrow.Origin = new Point3D(0, 0, size);
            zArrow.Direction = new Vector3D(0, 0, 1);
            zArrow.Diameter = thickness;
            zArrow.Point2 = new Point3D(0, 0, size + thickness * 2);
        }

        // 辅助方法：根据位置和方向设置变换
        public void SetPositionAndDirection(Point3D position, Vector3D direction, Vector3D up)
        {
            // 计算坐标系的右向量
            Vector3D zAxis = direction;
            zAxis.Normalize();

            Vector3D yAxis = up;
            yAxis.Normalize();

            Vector3D xAxis = Vector3D.CrossProduct(yAxis, zAxis);
            xAxis.Normalize();

            // 重新计算正交的 y 轴，确保正交
            yAxis = Vector3D.CrossProduct(zAxis, xAxis);

            // 构造变换矩阵
            Matrix3D matrix = new Matrix3D(
                xAxis.X, xAxis.Y, xAxis.Z, 0,
                yAxis.X, yAxis.Y, yAxis.Z, 0,
                zAxis.X, zAxis.Y, zAxis.Z, 0,
                position.X, position.Y, position.Z, 1);

            this.Transform = new MatrixTransform3D(matrix);
        }

        public void SetPosition(Point3D position)
        {
            var matrixTransform = this.Transform as MatrixTransform3D;
            if (matrixTransform != null)
            {
                var matrix = matrixTransform.Matrix;
                matrix.OffsetX = position.X;
                matrix.OffsetY = position.Y;
                matrix.OffsetZ = position.Z;
                this.Transform = new MatrixTransform3D(matrix);
            }
            else
            {
                // 如果没有变换，直接赋值平移
                this.Transform = new TranslateTransform3D(position.X, position.Y, position.Z);
            }
        }
    }
}
